﻿/* 
ArticlePrice - used to keep information about articles
It's generated in HTML by ServerSide data.
*/
var ArticlePrice = new Object();
ArticlePrice = function (price, sizeName, isKilo, articleId)
{
    this.Price = parseFloat(price);
    this.SizeName = sizeName;
    this.IsKilo = isKilo;
    this.ArticleId = articleId;
}

/* ************************ ************************ ************************
Price List object.
Contains information about the SizeTypeGroups and the SizeTypes.
It keeps the PriceList for the defined Article.

EVENTS :
SizeGroupChange() : called on SizeGroup DropDown change

SizeTypeChange() : called on SizeType DropDown change

QuantityChange() : called on Quantity TextBox change

AddToBasket() : Add selected article to the cart using JSON POST.
AddToBasketUrl : defines the URL to the above Action

RememberArticle() : Add selected article to the Remember User list.
RememberArticle : defines the URL to the Remember Article Action

=========


Init() : called ON START


GetArticlePriceBySelOpt() : return the ArticlePrice object by the selected SizeType DropDown item

GetQuantityFloat() : returns the current entered quantity number as Js float, or NULL if quantity is empty.
      
GetSelSizeGroupOpt() : returns the Selected Option in SizeGroup DropDown

GetGroupName() : retunrs the Name for the selected SizeGroup
 
GetCurrentPriceGroup() : returns the current SizeGroup array - depends on IsKilo() value

GetArticleInputModel() : Here is the Mapping from JavaScript ArticlePrice to ServerSide ArticleInputModel class.

SetQuantityFloat(quantity) : sets the user input localized quantity number using current NumberFormat.NumberDecimalSeparator.

SetPrice() : Caluclates and sets the Text in the Price box, by input ArticlePrice and CurrentPrice.

SetSizeName() : sets the displayed names of the corresponding SizeName elem. 

SetAmountSizeName() : sets the displayed names of the corresponding AmountSizeName elem.

BlockAddToBasket() : Locks or Unlocks the Add to Basket Button js event.

NumbersOnly() : OnKeyPress event validation, attached to the quantity_input TextBox.

ValidateAndFixInputQuantity() :Called in SetPrice(). Validate the user quantity input. Fix if wrong.

SendJSON() : Send a JSON HTTP POST to the Server with the Article Obj as parameter.
 
$.toJSON(obj) : external library function from "json.js" file. Wrapps Js objects to JSON representation.

RemoveAllSizeTypeOptions() : removes all options from the sizeType DropDown

AddSizeTypeSelOptions() : adds new SizeType DropDown options by current Options Group(KiloGroup or OtherGroup) - depends on IsKilo()

IsQuantitySet() : returns true, if quantity input textbox contains any value.

IsKilo() : returs True if GetSelSizeGroupOpt().value == 1;

*/

var PriceList = new Object();
PriceList = function () {
    /* LOCALIZED Numbers Decimal Separator - also used by user input validation NumbersOnly() */
    this.LocalizedNumberDecimalSeparator = JsConst.LocalizedNumberDecimalSeparator;
    this.JsNumberDecimalSeparator = JsConst.JsNumberDecimalSeparator;
    this.AllowedKeyValues = JsConst.AllowedKeyValues;
    this.FloatRegExp = JsConst.FloatRegExp;
    this.IntRegExp = JsConst.IntRegExp;
    this.QuantityValidationFailedVal = JsConst.QuantityValidationFailedVal;

    this.KiloShortcut = JsConst.KiloShortcut;

    this.RemoveFromBasketUrl = JsConst.RemoveFromBasketUrl;

    this.AddToBasketUrl = JsConst.AddToBasketUrl;
    this.RememberArticleUrl = JsConst.RememberArticleUrl;
    this.UpdateBasketUrl = JsConst.UpdateBasketUrl;


    this.ArrayOfArticlePrices = null;
    this.KiloGroup = new Array();
    this.OtherGroup = new Array();

    this.SizeGroupSelElem = null;
    this.SizeTypeSelElem = null;

    this.PriceTbxObj = null;
    this.SizeNameObj = null;
    this.AmountSizeNameObj = null;
    this.QuantityObj = null;


    this.AddtoBasketBtnObj = null;

    this.Init = function (arrayOfArticlePrices, sizeGroupSelId, sizeTypeSelId, priceTbxId, sizeNameId, amountSizeNameId, quantityId) {
        this.SizeGroupSelElem = $("#" + sizeGroupSelId).get(0);
        this.SizeTypeSelElem = $("#" + sizeTypeSelId).get(0);
        this.PriceTbxObj = $("#" + priceTbxId);
        this.SizeNameObj = $("#" + sizeNameId);
        this.AmountSizeNameObj = $("#" + amountSizeNameId);
        this.QuantityObj = $("#" + quantityId);

        this.ArrayOfArticlePrices = arrayOfArticlePrices;
        if (this.ArrayOfArticlePrices.length > 0) {
            var self = this;
            $.each(self.ArrayOfArticlePrices, function (index, price) {
                if (price.IsKilo == 1) {
                    self.KiloGroup.push(price);
                }
                else {
                    self.OtherGroup.push(price);
                }
            });

            /* Init dropdown group and type */
            this.SizeGroupChange();
        }
        else {
            alert(JsConst.ErrorMsg_PriceList_Init_ArticlePriceEmpty);
        }
    }
    /********************** EVENTS ***********/
    this.SizeGroupChange = function () {
        this.RemoveAllSizeTypeOptions();
        this.AddSizeTypeSelOptions();
        this.SetSizeName();
        this.SetAmountSizeName();
    }

    this.SizeTypeChange = function () {
        this.SetAmountSizeName();
        this.SetPrice(this.GetArticlePriceBySelOpt());
    }

    this.QuantityChange = function () {
        this.SetPrice(this.GetArticlePriceBySelOpt());
    }

    this.QuantityChangeWithSign = function (but_name) {
        this.SetPrice(this.GetArticlePriceBySelOpt());
        $('#' + but_name).addClass('basketButtonChangeActive');

    }



    /*--************* REMOVE ARTICLE FROM CART ************************-- */

    this.RemoveFromBasket = function (button, id) {

        var json = $.toJSON({ basketId: id + "" });
        var self = this;
        var url = this.RemoveFromBasketUrl;
        $.ajax({
            url: url,
            cache: false,
            type: 'POST',
            dataType: 'json',
            data: json,
            contentType: 'application/json; charset=utf-8',
            success: function (data) {
                location.reload(true);
            },
            error: function (xhr, ajaxOptions, thrownError) {
                alert('Error');
            }
        });
    }

    this.removeElement = function (divNum) {
        var d = document.getElementById('BasketItems');
        var olddiv = document.getElementById(divNum);
        d.removeChild(olddiv);
        Basket.Refresh();
    }

    /*--************* UPDATE ARTICLE FROM CART ************************-- */
    this.UpdateBasket = function (button, id) {
        var self = this;
        var url = this.UpdateBasketUrl;

        if (this.IsQuantitySet()) {
            var quantity = this.GetQuantityFloat();
            var articlePrice = this.GetArticlePriceBySelOpt();
            var json = $.toJSON(this.GetBasketItemInputModel(articlePrice, quantity, id));

            $.ajax({
                url: url,
                cache: false,
                type: 'POST',
                dataType: 'json',
                data: json,
                contentType: 'application/json; charset=utf-8',
                success: function (data) {
                    location.reload(true);
                },
                error: function (xhr, ajaxOptions, thrownError) {
                    alert('Error');
                }
            });
        }
    }


    this.GetBasketItemInputModel = function (articlePrice, quantity, id) {

        return (articlePrice == null) ? null : {
            BasketArticleId: id,
            ArticleId: articlePrice.ArticleId,
            SizeName: articlePrice.SizeName,
            Quantity: quantity
        };
    }

    /*--************* ADD ARTICLE TO CART ************************-- */

    this.AddToBasket = function (button) {
        this.AddtoBasketBtnObj = $(button);

        if (this.IsQuantitySet()) {
            var quantity = this.GetQuantityFloat();

            if (quantity > 0) {
                var articlePrice = this.GetArticlePriceBySelOpt();
                if (articlePrice != null) {
                    this.BlockAddToBasket(true);
                    this.SendJSON(articlePrice, quantity, this.AddToBasketUrl, this.CallBack_AddToBasket);
                }
                else {
                    alert(JsConst.ErrorMsg_PriceList_AddToCart_ArticlePriceNotFound);
                }
            }
            else {
                alert(JsConst.ErrorMsg_PriceList_AddToCart_ZeroQuantity);
            }
        }
        else {
            alert(JsConst.ErrorMsg_PriceList_AddToCart_NoQuantity);
        }
    }

    this.CallBack_AddToBasket = function (callBackData, self) {
        self.BlockAddToBasket(false);

        if (typeof (callBackData) == "object") {
            /*
            $("#dialog-AddToBasket-content")
            .html("<b>Received server-response:</b>:"
            + "<br/> BasketArticleId:" + callBackData.BasketArticleId
            + "<br/> ArticleId:" + callBackData.ArticleId
            + "<br/> SizeName:" + callBackData.SizeName
            + "<br/> Quantity:" + callBackData.Quantity
            );                    
            */

            Dialog.ShowAddToBasket();

            if (typeof (Basket) == "object") Basket.Refresh();
        }
        else {
            alert(JsConst.ErrorMsg_PriceList_CallBack_AddToCart_NotAnObject + "\n" + callBackData);
        }
    }

    /*--*************REMEMBER ARTICLE ***********************-- */

    this.RememberArticle = function () {
        var articlePrice = this.GetArticlePriceBySelOpt();
        if (articlePrice != null) {
            this.SendJSON(articlePrice, 0, this.RememberArticleUrl, this.CallBack_RememberArticle);
        }
        else {
            alert(JsConst.ErrorMsg_PriceList_RememberArticle_ArticlePriceNotFound);
        }
    }

    this.CallBack_RememberArticle = function (callBackData, self) {
        if (typeof (callBackData) == "object") {
            alert("It works! Server RememberArticle Action received this:"
            + "<br/>ArticleId:" + callBackData.ArticleId
            + "<br/>SizeName:" + callBackData.SizeName
            + "<br/>nQuantity:" + callBackData.Quantity);
        }
        else {
            alert(JsConst.ErrorMsg_PriceList_CallBack_RememberArticle_NotAnObject);
        }
    }

    /*--************* SEND JSON ************************-- */
    this.SendJSON = function (articlePrice, quantity, url, callBack) {
        if (url + '' == '') {
            alert(JsConst.ErrorMsg_PriceList_SendJSON_UrlEmpty);
            return;
        }
        /* Map the js object to serverside class representation */
        var article = this.GetArticleInputModel(articlePrice, quantity);

        if (article == null) {
            alert(JsConst.ErrorMsg_PriceList_SendJSON_ArticleObjectNull);
            return;
        }

        var json = $.toJSON(article);

        var self = this;

        $.ajax({
            url: url,
            cache: false,
            type: 'POST',
            dataType: 'json',
            data: json,
            contentType: 'application/json; charset=utf-8',
            success: function (data) {
                /* get the result and do some magic with it*/
                callBack(data, self);
            },
            error: function (xhr, ajaxOptions, thrownError) {
                callBack(xhr.status + ":" + thrownError, self);
            }
        });
    }

    /*--************* ***********************-- */

    this.GetArticleInputModel = function (articlePrice, quantity) {
        /* 
        Here is the Mapping from JavaScript ArticlePrice to ServerSide ArticleInputModel class. 
               
        TODO: Check the ServerSide Quantity NumberDecimalSeparator. 
        If it's also Localized, replace the quantity JsNumberDecimalSeparator by LocalizedNumberDecimalSeparator.
        */
        return (articlePrice == null) ? null : { ArticleId: articlePrice.ArticleId, SizeName: articlePrice.SizeName, Quantity: quantity };
    }


    this.ValidateAndFixInputQuantity = function () {
        if (this.IsQuantitySet()) {
            var val = this.QuantityObj.val();

            if (this.IsKilo()) {
                if (this.FloatRegExp.test(val) == false) {
                    var val = this.GetQuantityFloat();
                    if (val == null || isNaN(val)) val = this.QuantityValidationFailedVal;

                    this.SetQuantityFloat(val);
                }
            }
            else {
                if (this.IntRegExp.test(val) == false) {
                    var val = parseInt(val);
                    if (isNaN(val)) val = this.QuantityValidationFailedVal;

                    this.QuantityObj.val(val);
                }
            }
        }
    }

    this.BlockAddToBasket = function (val) {
        if (this.AddtoBasketBtnObj != null) {
            if (val == true) {
                this.AddtoBasketBtnObj.attr('disabled', true);
            }
            else {
                this.AddtoBasketBtnObj.attr('disabled', false);
            }
        }
    }

    this.NumbersOnly = function (e) {
        var key;
        var keychar;

        if (window.event) {
            key = window.event.keyCode;
        }
        else if (e) {
            key = e.which;
        }
        else {
            return true;
        }
        keychar = String.fromCharCode(key);

        if ((key == null) || (key == 0) || (key == 8) || (key == 9) || (key == 13) || (key == 27)) {
            return true;
        }
        else if (((this.AllowedKeyValues).indexOf(keychar) > -1)) {
            return true;
        }
        else if (this.IsKilo() && (keychar == this.LocalizedNumberDecimalSeparator)
                    && this.QuantityObj.val().indexOf(this.LocalizedNumberDecimalSeparator) == -1) {
            return true;
        }
        else
            return false;
    }

    this.IsQuantitySet = function () {
        var quantityStr = this.QuantityObj.val() + "";

        return quantityStr != "" && quantityStr != this.LocalizedNumberDecimalSeparator;
    }

    this.GetQuantityFloat = function () {
        if (this.IsQuantitySet()) {
            return parseFloat(this.QuantityObj.val().replace(this.LocalizedNumberDecimalSeparator, this.JsNumberDecimalSeparator));
        }
        else {
            return null;
        }
    }
    this.SetQuantityFloat = function (quantity) {
        this.QuantityObj.val(quantity.toFixed(2).replace(".", this.LocalizedNumberDecimalSeparator).replace(",", this.LocalizedNumberDecimalSeparator));
    }
    this.RemoveAllSizeTypeOptions = function () {
        var self = this;
        $.each(self.SizeTypeSelElem.options, function () {
            self.SizeTypeSelElem.remove(0);
        });
    }
    this.GetArticlePriceBySelOpt = function () {
        var retVal = null;

        var selVal = this.SizeTypeSelElem.options[this.SizeTypeSelElem.selectedIndex].value;
        if (selVal != null) {
            var self = this;
            $.each(self.ArrayOfArticlePrices, function (index, price) {
                if (price.SizeName == selVal) {
                    retVal = price;
                }
            });
        }
        return retVal;
    }

    this.AddSizeTypeSelOptions = function () {
        var group = this.GetCurrentPriceGroup();

        var self = this;
        $.each(group, function (index, price) {
            /* Create an Option obj*/
            var opt = document.createElement("option");
            /* Add an Option object to Drop Down/List Box*/
            self.SizeTypeSelElem.options.add(opt);
            /* Assign text and value to Option object*/
            opt.text = price.SizeName;
            opt.value = price.SizeName;
        });

        this.SetPrice(group[0]);
    }

    this.SetPrice = function (articlePrice) {
        var price = articlePrice.Price;

        if (this.IsQuantitySet()) {
            this.ValidateAndFixInputQuantity();

            price = price * this.GetQuantityFloat();
        }
        /* It's the price from dataBase: assume it can be , or . So always replace it to the Culture Specific NumberDecimalSeparator. */
        this.PriceTbxObj.text(price.toFixed(2).replace(".", this.LocalizedNumberDecimalSeparator).replace(",", this.LocalizedNumberDecimalSeparator));

    }
    this.GetSelSizeGroupOpt = function () {
        return this.SizeGroupSelElem.options[this.SizeGroupSelElem.selectedIndex];
    }
    this.GetSelSizeTypeOpt = function () {
        return this.SizeTypeSelElem.options[this.SizeTypeSelElem.selectedIndex];
    }
    this.IsKilo = function () {
        return this.GetSelSizeGroupOpt().value == 1;
    }
    this.GetGroupName = function () {
        return this.IsKilo() ? this.KiloShortcut : this.GetSelSizeGroupOpt().text;
    }
    this.GetCurrentPriceGroup = function () {
        return this.IsKilo() ? this.KiloGroup : this.OtherGroup;
    }
    this.SetSizeName = function () {
        this.AmountSizeNameObj.text(this.GetGroupName());
    }
    this.SetAmountSizeName = function () {
        this.SizeNameObj.text(this.GetSelSizeTypeOpt().text);
    }
}